package com.pactera.madp.cp.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.cp.api.dto.track.BehaviorTrackDto;
import com.pactera.madp.cp.api.em.workcontact.EventEnum;
import com.pactera.madp.cp.api.entity.*;
import com.pactera.madp.cp.common.constant.Constant;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.service.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

import static com.pactera.madp.cp.common.constant.WxCallbackConst.*;

@Slf4j
@Service
@Transactional(rollbackFor = {RuntimeException.class, Exception.class})
public class WxCallbackContactServiceImp implements IWxCallbackContactService {

    @Autowired
    private IContactService contactService;
    @Autowired
    private ICorpService corpService;
    @Autowired
    private BehaviorTrackService behaviorTrackService;
    @Autowired
    private ContactUniqueQrCodeService contactUniqueQrCodeService;
    @Autowired
    private ContactRelationService contactRelationService;
    @Autowired
    private IWorkEmployeeService workEmployeeService;
    @Resource
    private ContactEmployeeTrackService contactEmployeeTrackService;

    @Override
    public String dispatchEvent(String dataJson) {
        JSONObject jsonObject = JSON.parseObject(dataJson);
        int corpId = jsonObject.getIntValue("corpId");
        CorpContextHolder.setCorpId(corpId);
        JSONObject xmlJsonObject = jsonObject.getJSONObject("xml");
        String changeType = xmlJsonObject.getString("changetype");
        String wxCorpId = xmlJsonObject.getString("tousername");

        String externaluserid = xmlJsonObject.getString("externaluserid");
        String userid = xmlJsonObject.getString("userid");

        //客户回调
        if (ADD_EXTERNAL_CONTACT.equals(changeType)) {
            contactService.addExternalContact(wxCorpId, externaluserid, userid, xmlJsonObject.getString("welcomecode"), xmlJsonObject.getString("state"));
        }
        if (EDIT_EXTERNAL_CONTACT.equals(changeType)) {
            contactService.editExternalContact(externaluserid, userid);
        }
        if (DEL_EXTERNAL_CONTACT.equals(changeType)) {
            contactService.deleteExternalContact(externaluserid, userid,xmlJsonObject.getString("source"));
        }

        if (DEL_FOLLOW_USER.equals(changeType)) {
            contactService.externalContactDeleteEmployee(externaluserid, userid);
        }
        return "";
    }

    @Override
    public String callback(String dataJson) {
        JSONObject jsonObject = JSON.parseObject(dataJson);
        //int corpId = jsonObject.getIntValue("corpId");
        JSONObject xmlJsonObject = jsonObject.getJSONObject("xml");
        String changeType = xmlJsonObject.getString("changetype");
        String wxCorpId = xmlJsonObject.getString("tousername");

        //客户回调
        if (ADD_EXTERNAL_CONTACT.equals(changeType)) {
            return addCallback(xmlJsonObject);
        }
        if (EDIT_EXTERNAL_CONTACT.equals(changeType)) {

        }
        if (DEL_EXTERNAL_CONTACT.equals(changeType)) {

        }
        if (DEL_FOLLOW_USER.equals(changeType)) {
            return delCallback(xmlJsonObject);
        }
        return "";
    }

    @SneakyThrows
    private String addCallback(JSONObject xmlJsonObject) {
        String wxCorpId = xmlJsonObject.getString("tousername");
        String wxUserId = xmlJsonObject.getString("userid");
        String externalUserId = xmlJsonObject.getString("externaluserid");
        CorpEntity corp = corpService.getCorpByWxCorpId(wxCorpId);
        if(corp == null) {
            log.error("企业" + wxCorpId + "不存在");
            return "";
        }
        Integer corpId = corp.getCorpId();

        //记录客户邀请关系
        saveContactRelation(wxUserId, corpId, externalUserId, xmlJsonObject);

        //为新添加客户生成专属二维码
        /*ContactUniqueQrCodeDto dto = new ContactUniqueQrCodeDto();
        dto.setWxUserId(wxUserId);
        dto.setWxExternalUserid(externalUserId);
        dto.setOperType(0);
        contactUniqueQrCodeService.getUniqueQrCode(dto);*/

        return "";
    }

    @SneakyThrows
    private String delCallback(JSONObject xmlJsonObject) {
        log.info("用户删除成员回调处理开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        String wxCorpId = xmlJsonObject.getString("tousername");
        String wxUserId = xmlJsonObject.getString("userid");
        String externalUserId = xmlJsonObject.getString("externaluserid");
        CorpEntity corp = corpService.getCorpByWxCorpId(wxCorpId);
        if(corp == null) {
            log.error("企业" + wxCorpId + "不存在");
            return "";
        }
        Integer corpId = corp.getCorpId();

        BehaviorTrackDto dto = new BehaviorTrackDto();
        dto.setEvent("lost");
        dto.setCorpId(corpId);
        dto.setWxUserId(wxUserId);
        dto.setWxExternalUserid(externalUserId);
        log.info("behaviorTrackDto:{}",dto);
        behaviorTrackService.handleTrack(dto, null);
        log.info("用户删除成员回调处理结束>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        return "";
    }

    /**
     * 记录客户邀请关系
     * @param corpId
     * @param externalUserId
     */
    private void saveContactRelation(String wxUserId, Integer corpId, String externalUserId, JSONObject xmlJsonObject) {
        try {
            /*String respJson = WxApiUtils.getExternalContactInfo(corpId, externalUserId);
            if(respJson == null) {
                log.error("被邀请客户详情查询失败：{}",externalUserId);
                return;
            }*/
            String state = xmlJsonObject.getString("state");
            if(StrUtil.isNotEmpty(state) && state.startsWith(Constant.UQC_PREFIX)) {
                String[] ids = state.replace(Constant.UQC_PREFIX,"").split("-");
                //获取邀请客户主键id
                Integer contactId = Integer.valueOf(ids[0]);
                //获取企业成员主键id
                Integer employeeId = Integer.valueOf(ids[1]);
                //获取受邀请客户主键id
                Integer joinContactId = contactService.getContactId(externalUserId, corpId);
                //保存关系
                ContactRelation entity = new ContactRelation();
                entity.setContactId(contactId);
                entity.setEmployeeId(employeeId);
                entity.setJoinContactId(joinContactId);
                //先校验是否已存
                int count = contactRelationService.count(Wrappers.query(entity));
                if(count < 1) {
                    BehaviorTrackEntity behaviorTrackEntity = new BehaviorTrackEntity();
                    behaviorTrackEntity.setWxUserId(wxUserId);
                    behaviorTrackEntity.setWxExternalUserid(externalUserId);
//                    saveTrack(joinContactId, behaviorTrackEntity);
//                    saveTrack(employeeId, contactId, joinContactId);
                    String errorMsg = contactRelationService.save(entity) ? "保存客户关系成功" : "保存客户关系失败";
                    log.error(errorMsg);
                }
            }
        }catch (Exception e) {
            log.error("保存客户关系失败",e);
        }
    }

    @SneakyThrows
    private void saveTrack(Integer joinContactId, BehaviorTrackEntity entity) {

        String wxUserId = entity.getWxUserId();
        Integer corpId = CorpContextHolder.getCorpId();
        String externalUserId = entity.getWxExternalUserid();
        //查询成员信息
        WorkEmployeeEntity employeeEntity = workEmployeeService.getWorkEmployeeByCorpIdAndWxUserId(corpId, wxUserId);
        if(employeeEntity == null) {
            throw new CheckedException("企业" + corpId + "成员" + wxUserId + "不存在");
        }
        entity.setUsername(employeeEntity.getName());
        entity.setCorpId(employeeEntity.getCorpId());
        entity.setEmployeeId(employeeEntity.getId());
        //查询联系人信息
        WorkContactEntity contactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId,corpId)
                .eq(WorkContactEntity::getWxExternalUserid, externalUserId),false);
        if(contactEntity == null) {
            throw new CheckedException("企业" + corpId + "外部联系人" + externalUserId + "不存在");
        }
        entity.setExternalUsername(contactEntity.getName());
        entity.setContactId(contactEntity.getId());
        Integer contactId = entity.getContactId();
        Integer employeeId = entity.getEmployeeId();
        //查询联系人信息
        WorkContactEntity joinContactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId, corpId)
                .eq(WorkContactEntity::getId, joinContactId),false);
        if(joinContactEntity == null) {
            return;
        }
        String joinExternalUsername = joinContactEntity.getName();
        if (employeeId == null || contactId == null || StringUtils.isAnyEmpty(
                entity.getExternalUsername(),
                entity.getUsername(),
                joinExternalUsername
        )) {
            log.error("轨迹条件不满足：{}", entity.toString());
            return;
        }
        List<String> datas = new ArrayList<>();
        datas.add(joinExternalUsername);
        datas.add(entity.getUsername());
        datas.add(entity.getExternalUsername());
        datas.add(entity.getUsername());
        String content = String.format("【%s】通过扫描客户经理【%s】与客户【%s】的一客一码成为客户经理【%s】的客户", datas.toArray(new String[datas.size()]));



        //保存轨迹 channel:2-侧边栏
        contactService.saveTrack(employeeId, contactId, EventEnum.CREATE, content,2, entity.getCorpId());
    }

    @SneakyThrows
    private void saveTrack(Integer employeeId, Integer contactId, Integer joinContactId) {
        Integer corpId = CorpContextHolder.getCorpId();
        //查询成员信息
        WorkEmployeeEntity employeeEntity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getCorpId, corpId)
                .eq(WorkEmployeeEntity::getId, employeeId),false);
        if(employeeEntity == null) {
            return;
        }
        String employeeName = employeeEntity.getName();

        //查询联系人信息
        WorkContactEntity contactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId, corpId)
                .eq(WorkContactEntity::getId, contactId),false);
        if(contactEntity == null) {
            return;
        }
        String contactName = contactEntity.getName();

        //查询联系人信息
        WorkContactEntity joinContactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId, corpId)
                .eq(WorkContactEntity::getId, joinContactId),false);
        if(joinContactEntity == null) {
            return;
        }
        String joinContactName = joinContactEntity.getName();
        if (employeeId == null || contactId == null || StringUtils.isAnyEmpty(
                employeeName,
                contactName,
                joinContactName
        )) {
            log.error("轨迹条件不满足：{}");
            return;
        }
        List<String> datas = new ArrayList<>();
        datas.add(joinContactName);
        datas.add(employeeName);
        datas.add(contactName);
        datas.add(employeeName);
        String content = String.format("【%s】通过扫描客户经理【%s】与客户【%s】的一客一码成为客户经理【%s】的客户", datas.toArray(new String[datas.size()]));

        //保存轨迹 channel:2-侧边栏
//
        List<ContactEmployeeTrackEntity> entities = contactEmployeeTrackService.list(
                Wrappers.<ContactEmployeeTrackEntity>lambdaQuery()
                .eq(ContactEmployeeTrackEntity::getEmployeeId, employeeId)
                .eq(ContactEmployeeTrackEntity::getContactId, joinContactId)
                .eq(ContactEmployeeTrackEntity::getChannel, 2)
                .eq(ContactEmployeeTrackEntity::getCorpId, corpId)
                .eq(ContactEmployeeTrackEntity::getEvent, EventEnum.CREATE)
                .orderByDesc(ContactEmployeeTrackEntity::getCreateTime)
        );
        if (entities == null || entities.size() < 1) {
            contactService.saveTrack(employeeId, joinContactId, EventEnum.CREATE, content,2, corpId);
        } else {
            ContactEmployeeTrackEntity entity = entities.get(0);
            entity.setContent(content);
            contactEmployeeTrackService.updateById(entity);
        }

    }

}
